package controller

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
	validator "gopkg.in/go-playground/validator.v8"
	"inspur.com/cloudware/conf"
	"inspur.com/cloudware/serializer"
	"inspur.com/cloudware/util"
	"inspur.com/cloudware/wscomm/wsserver"
)

type Sheldon struct {
	Name   string `json:"name" binding:"required,min=2,max=30"`
	Salary int    `json:"salary"`
	Sex    bool   `json:"sex"`
}

var upgrader = websocket.Upgrader{
	// 解决跨域问题
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// Ping 状态检查接口
// @Summary Ping
// @Description 状态检查接口
// @Accept  json
// @Produce  json
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Success 200
// @Failure 500
// @Router /api/v1/ping [post]
func Ping(c *gin.Context) {
	c.JSON(200, serializer.Response{
		Code: 0,
		Msg:  "Pong",
	})
}

// TestLog 测试日志接口
// @Summary TestLog
// @Description 测试日志接口
// @Accept  json
// @Produce  json
// @param name path string true "cloudware says hello to world"
// @Success 200
// @Failure 500
// @Router /api/v1/testlog [get]
func TestLog(c *gin.Context) {
	testgetparam := c.Query("name")
	if testgetparam != "" {
		util.Log().Error("%s's cloudware says hello to world", testgetparam)
	}
	c.JSON(200, serializer.Response{
		Code: 0,
		Msg:  "cloudware says hello to world",
	})
}

// TestPost 测试post接口  不定义类型   直接取参数
// @Summary TestPost
// @Description 测试post接口
// @Accept  json
// @Produce  json
// @param name path string true "cloudware says hello to world"
// @Success 200
// @Failure 500
// @Router /api/v1/TestPost [post]
func TestPost(c *gin.Context) {
	user := c.DefaultPostForm("player", "Sheldon")
	salary := c.PostForm("salary")

	util.Log().Error("%s's cloudware says hello to world", user)
	util.Log().Error("%s's cloudware says hello to world %s", user, salary)
	c.JSON(200, serializer.Response{
		Code: 0,
		Msg:  "cloudware says hello to world",
	})
}

// TestPostStruct 测试post接口  不定义类型   直接取参数
// @Summary TestPostStruct
// @Description 测试post接口
// @Accept  json
// @Produce  json
// @param name path string true "cloudware says hello to world"
// @Success 200
// @Failure 500
// @Router /api/v1/TestPostStruct [post]
func TestPostStruct(c *gin.Context) {
	p := Sheldon{}
	//要求body格式为json   自动解析为代码中的对象
	err := c.ShouldBindJSON(&p)
	if err != nil {
		c.JSON(400, gin.H{
			"msg":  "出错！",
			"data": gin.H{},
		})
	} else {
		c.JSON(200, gin.H{
			"msg":  "success",
			"data": p,
		})
	}
}

func WsConnectTest(c *gin.Context) {
	ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer ws.Close()
	for {
		_, message, err := ws.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", "收到一条消息")
		log.Printf("内容是: %s", message)
		err = ws.WriteMessage(websocket.TextMessage, []byte("我是Sheldon的server"))
		if err != nil {
			log.Println("write:", err)
			break
		}
	}
}

func WsConnect(c *gin.Context) {
	wsserver := wsserver.GetWsServer()
	wsserver.Connect(c)
}

func SendMsgToAgent(c *gin.Context) {
	wsserver := wsserver.GetWsServer()
	hostId := c.Param("hostid")
	data, _ := c.GetRawData()
	err := wsserver.WriteMessageToAgent(hostId, data)
	if err != nil {
		c.JSON(400, gin.H{
			"msg":  "session not found",
			"data": err.Error(),
		})
	} else {
		c.JSON(200, gin.H{
			"msg": "success",
		})
	}

}

func GetOnlineAgents(c *gin.Context) {

	wsserver := wsserver.GetWsServer()
	sessions := wsserver.GetSessionsList()
	for index, v := range sessions {
		logrus.Infof("get a new agent connect index %v, hostid %s", index, v.AgentID)
	}
	c.JSON(200, gin.H{
		"msg":  "getagents!",
		"data": sessions,
	})

}

// ErrorResponse 返回错误消息
func ErrorResponse(err error) serializer.Response {
	if ve, ok := err.(validator.ValidationErrors); ok {
		for _, e := range ve {
			field := conf.T(fmt.Sprintf("Field.%s", e.Field))
			tag := conf.T(fmt.Sprintf("Tag.Valid.%s", e.Tag))
			return serializer.ParamErr(
				fmt.Sprintf("%s%s", field, tag),
				err,
			)
		}
	}
	if _, ok := err.(*json.UnmarshalTypeError); ok {
		return serializer.ParamErr("JSON类型不匹配", err)
	}

	return serializer.ParamErr("参数错误", err)
}
